package intelligentcity.model.traffic;

import intelligentcity.model.Move;
import intelligentcity.model.Point;
import intelligentcity.model.Road;
import intelligentcity.model.streets.OneWayStreet;

public abstract class Behaviour implements IBehaviour {

    protected final Car car;
    protected final Traffic traffic;
    protected final Road currentRoad;

    protected OneWayStreet currentOWS;
    protected Point point;

    public Behaviour(Car car) {
        super();
        this.car = car;
        this.traffic = car.getTraffic();
        this.currentRoad = car.getCurrentRoad();
        this.currentOWS = car.getCurrentOWS();
        this.point = car.getPoint();
    }

    @Override
    public boolean canIMove(Move move, int distance) {
        // pierwszy arg toCase powinien miec wieksza wartosc
        try {
            switch (move) {
                case UP: {
                    for (Integer i : traffic.getCars().keySet()) {
                        if (!car.isWillingToTurnLeft() && point.getX() == traffic.getCars().get(i).getPoint().getX()) { // NullPointerException
                            if (toClose(point.getY(), traffic.getCars().get(i).getPoint().getY(), distance)) {
                                return false;
                            }
                        }

                    }
                    break;
                }
                case DOWN: {
                    for (Integer i : traffic.getCars().keySet()) {
                        if (!car.isWillingToTurnLeft() && point.getX() == traffic.getCars().get(i).getPoint().getX()) {// NullPointerException
                            if (toClose(traffic.getCars().get(i).getPoint().getY(), point.getY(), distance)) {
                                return false;
                            }
                        }
                    }
                    break;
                }
                case LEFT: {
                    for (Integer i : traffic.getCars().keySet()) {
                        if (!car.isWillingToTurnLeft() && point.getY() == traffic.getCars().get(i).getPoint().getY()) {// NullPointerException
                            if (toClose(point.getX(), traffic.getCars().get(i).getPoint().getX(), distance)) {
                                return false;
                            }
                        }
                    }
                    break;
                }
                case RIGHT: {
                    for (Integer i : traffic.getCars().keySet()) {
                        if (!car.isWillingToTurnLeft() && point.getY() == traffic.getCars().get(i).getPoint().getY()) {// NullPointerException
                            if (toClose(traffic.getCars().get(i).getPoint().getX(), point.getX(), distance)) {
                                return false;
                            }
                        }
                    }
                    break;
                }
            }
        } catch (NullPointerException e) {
            return false;
        }
        return true;
    }

    private boolean toClose(int front, int back, int distance) {
        if (front - back < distance && front - back > 0) {
            return true;
        }
        return false;
    }
}
